package cn.zenith.lucene.demo;

import java.io.IOException;
import java.text.Format;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.Locale;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.core.SimpleAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;

public class LuceneDao extends LuceneBase {

	/**
	 * 静态代码块儿为了赋值方便
	 */
	static {
		String path = "E:\\luceneIndex";
		try {
			setDirectory(path);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) throws Exception {
		// System.out.println(MessageFormat.format("sdfaf{0}sdf","111"));
		//displayalltoken();
		 add();
		// System.out.println(findIndexDbCount());
		// updateByID("2");
		// searchTermQuery("name", "哈利波特");
		// delete("0");
	}

	/**
	 * 添加路径
	 * 
	 * @param indexWriterPath
	 * @author zenith
	 * @date 2014年3月27日 下午1:44:02
	 */
	static void add() {
		try {
			indexWriter.deleteAll();

			Document document1 = new Document();
			// 存储
			// StringFied是没有分词，只能通过完整的文字搜索出来
			// TextField 是有分词具体由analyzer 决定
			document1.add(new StringField("id", "1", Store.YES));
			document1
					.add(new StringField("name", "StringField的哈利波特", Store.YES));
			document1.add(new TextField("content", "千山鸟飞绝，万径人踪灭。", Store.YES));
			// 添加进写入流里
			indexWriter.addDocument(document1);

			Document document2 = new Document();
			// 存储
			// StringFied是没有分词，只能通过完整的文字搜索出来
			document2.add(new StringField("id", "2", Store.YES));
			document2.add(new TextField("name", "TextField的哈利波特", Store.YES));
			document2.add(new TextField("content", "孤舟蓑笠翁，独钓寒江雪。", Store.YES));
			// 添加进写入流里
			indexWriter.addDocument(document2);

			Document document3 = new Document();
			// 存储
			// StringFied是没有分词，只能通过完整的文字搜索出来
			document3.add(new StringField("id", "3", Store.YES));
			document3.add(new TextField("name", "小朋友", Store.YES));
			document3.add(new TextField("content", "祖国的花朵", Store.YES));
			// 添加进写入流里
			indexWriter.addDocument(document3);

			// 优化压缩段,大规模添加数据的时候建议，少使用本方法，会影响性能
			// indexWriter.forceMerge(1);
			// 提交数据
			indexWriter.commit();
			System.out.println("添加成功");

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeall();
		}
	}

	/**
	 * 根据id删除
	 * 
	 * @param id
	 * @author zenith
	 * @date 2014年3月27日 下午3:28:41
	 */
	static void delete(String id) {

		try {

			IndexReader indexReader = DirectoryReader.open(directory);
			Query q = new TermQuery(new Term("id", id));
			indexWriter.deleteDocuments(q);
			indexWriter.commit();
			indexReader.close();
			System.out.println("删除id为" + id + "的记录成功");

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeall();
		}
	}

	/**
	 * 更新
	 * 
	 * @param indexPath
	 * @param docID
	 * @param map
	 * @author zenith
	 * @date 2014年3月27日 下午3:48:28
	 */
	static void updateByID(String docID) {

		try {
			IndexReader indexReader = DirectoryReader.open(directory);
			Document document = new Document();
			// id不变
			document.add(new StringField("id", docID, Store.YES));
			document.add(new StringField("name", "嘻嘻", Store.YES));
			document.add(new TextField("content", "好人一生平安", Store.YES));
			indexWriter.updateDocument(new Term("id", docID), document);
			indexWriter.commit();
			indexReader.close();
			System.out.println("更新成功!");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeall();
		}
	}

	/**
	 * 查总数
	 * 
	 * @return
	 * @author zenith
	 * @date 2014年3月27日 下午3:54:15
	 */
	static int findIndexDbCount() {
		int total = 0;
		try {
			IndexReader indexReader = DirectoryReader.open(directory);
			// 数据总量
			total = indexReader.numDocs();
			indexReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeall();
		}
		return total;
	}

	/**
	 * 简单查询
	 * 
	 * @param field
	 * @param searchText
	 * @author zenith
	 * @date 2014年3月27日 下午4:10:49
	 */
	static void searchTermQuery(String field, String searchText) {
		try {
			// 初始化查询组件
			IndexSearcher indexSearcher = new IndexSearcher(
					DirectoryReader.open(directory));
			// 查询
			Query query = new TermQuery(new Term(field, searchText));
			TopDocs topDocs = indexSearcher.search(query, 1000);
			for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
				// 根据scoreDoc获取doc的index然后用indexSearcher获取doc对象
				Document document = indexSearcher.doc(scoreDoc.doc);
				System.out.println("id:" + document.get("id"));
				System.out.println("name:" + document.get("name"));
				System.out.println("content:" + document.get("content"));
				System.out.println(document);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	static void closeall() {

		if (indexWriter != null) {
			try {
				// 关闭流
				indexWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (directory != null) {
			try {
				// 关闭流
				directory.close();

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	static void displayalltoken() throws Exception {
		IndexReader indexReader = DirectoryReader.open(directory);
		int count = indexReader.numDocs();
		for (int i = 0; i < count; i++) {
			System.out.println("第" + (i + 1) + "个Doc");
			// CJKAnalyzer 分析方法:交叉双字分割
			// StandardAnalyzer 分析方法：默认没有词只有字
			// ChineseAnalyzer 分析方法:基本等同StandardAnalyzer
			for (IndexableField field : indexReader.document(i).getFields()) {
				displayToken(indexReader.document(i), field,
						new StandardAnalyzer(Version.LUCENE_47));
			}
		}
	}

	/**
	 * 查看所有的token
	 * 
	 * @param stream
	 * @author zenith
	 * @date 2014年3月28日 下午4:11:11
	 */
	private static void displayToken(Document document, IndexableField field,
			Analyzer analyzer) {
		try {
			TokenStream stream = document.getField(field.name()).tokenStream(
					analyzer);
			analyzer.close();

			// 创建一个属性，这个属性会添加流中，随着这个TokenStream增加
			CharTermAttribute cta = stream
					.addAttribute(CharTermAttribute.class);
			stream.reset();// 不添加会显示空指针错误
			System.out.print(field.name() + ":" + field.stringValue()
					+ "*****所有token:");
			while (stream.incrementToken()) {
				System.out.print("[" + cta + "]");
			}
			System.out.println();
			stream.end();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
